package ai.leinao.notify.core.template;

import ai.leinao.notify.core.enums.NotifyType;
import lombok.AllArgsConstructor;
import lombok.NonNull;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 模板管理器抽象实现
 *
 * @author zhong.wang
 * @date 2025/7/8
 */
@AllArgsConstructor
public abstract class AbstractTemplateRegistry implements TemplateRegistry {
    /**
     * 模板供应商容器
     * key: notifyType
     * value: key: providerId value: TemplateProvider
     */
    protected final Map<String, Map<String,TemplateProvider>> templateProviderMap = new ConcurrentHashMap<>();

    /**
     * 模板容器
     */
    protected final Map<String,Template> templateMap = new ConcurrentHashMap<>();

    /**
     * 注册模板供应商
     *
     * @param provider
     */
    protected void registerProvider(TemplateProvider provider){
        if(!templateProviderMap.containsKey(provider.getNotifyType().getType())){
            templateProviderMap.put(provider.getNotifyType().getType(), new ConcurrentHashMap<>());
        }
        templateProviderMap.get(provider.getNotifyType().getType()).put(provider.getProvider(), provider);
    }


    /**
     * 根据通知类型和模板id获取模板属性
     *
     * @param notifyType
     * @param templateId
     * @return
     */
    protected abstract TemplateProperties getProperties(NotifyType notifyType, String templateId);

    /**
     * 根据通知类型和模板id获取模板
     *
     * @param notifyType 通知类型
     * @param templateId 模板id
     * @return
     * @param <T>
     */
    @Override
    @NonNull
    public <T extends Template> T getTemplate(@NonNull NotifyType notifyType, @NonNull String templateId) {
        if(templateMap.containsKey(templateId)){
            return (T) templateMap.get(templateId);
        }
        TemplateProperties properties = getProperties(notifyType, templateId);
        if(Objects.nonNull(properties)){
            T template = createTemplate(notifyType, properties);
            templateMap.put(templateId, template);
            return template;
        }
        return null;
    }


    /**
     * 根据通知类型和属性创建模板
     *
     *
     * @param notifyType 通知类型
     * @param properties 属性
     * @return {@link Template}
     */
    @Override
    @NonNull
    public <T extends Template> T createTemplate(@NonNull NotifyType notifyType, @NonNull TemplateProperties properties) {
        if(!templateProviderMap.containsKey(notifyType.getType())){
            throw new UnsupportedOperationException("不支持该通知类型:"+ notifyType.getType());
        }
        else {
            Map<String,TemplateProvider> providerMap = this.templateProviderMap.get(notifyType.getType());
            if(!providerMap.containsKey(properties.getProvider())){
                throw new UnsupportedOperationException("不支持该供应商:"+ properties.getProvider());
            }else{
                TemplateProvider provider = providerMap.get(properties.getProvider());
                T template = (T) provider.createTemplate(properties);
                return template;
            }
        }
    }

}
